home *** CD-ROM | disk | FTP | other *** search
/ Aminet 49 / Aminet 49 (2002)(GTI - Schatztruhe)[!][Jun 2002].iso / Aminet / util / libs / ttrender.lha / ttrender-2.0 / Developer / source / base / ftglyph.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-04-06  |  18.2 KB  |  680 lines

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ftglyph.c                                                              */
  4. /*                                                                         */
  5. /*    FreeType convenience functions to handle glyphs (body).              */
  6. /*                                                                         */
  7. /*  Copyright 1996-2001 by                                                 */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9. /*                                                                         */
  10. /*  This file is part of the FreeType project, and may only be used,       */
  11. /*  modified, and distributed under the terms of the FreeType project      */
  12. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13. /*  this file you indicate that you have read the license and              */
  14. /*  understand and accept it fully.                                        */
  15. /*                                                                         */
  16. /***************************************************************************/
  17.  
  18.   /*************************************************************************/
  19.   /*                                                                       */
  20.   /*  This file contains the definition of several convenience functions   */
  21.   /*  that can be used by client applications to easily retrieve glyph     */
  22.   /*  bitmaps and outlines from a given face.                              */
  23.   /*                                                                       */
  24.   /*  These functions should be optional if you are writing a font server  */
  25.   /*  or text layout engine on top of FreeType.  However, they are pretty  */
  26.   /*  handy for many other simple uses of the library.                     */
  27.   /*                                                                       */
  28.   /*************************************************************************/
  29.  
  30.  
  31. #include <ft2build.h>
  32. #include FT_GLYPH_H
  33. #include FT_OUTLINE_H
  34. #include FT_INTERNAL_OBJECTS_H
  35.  
  36.  
  37.   /*************************************************************************/
  38.   /*                                                                       */
  39.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  40.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  41.   /* messages during execution.                                            */
  42.   /*                                                                       */
  43. #undef  FT_COMPONENT
  44. #define FT_COMPONENT  trace_glyph
  45.  
  46.  
  47.   /*************************************************************************/
  48.   /*************************************************************************/
  49.   /****                                                                 ****/
  50.   /****   Convenience functions                                         ****/
  51.   /****                                                                 ****/
  52.   /*************************************************************************/
  53.   /*************************************************************************/
  54.  
  55.  
  56.   /* documentation is in ftglyph.h */
  57.  
  58.   FT_EXPORT_DEF( void )
  59.   FT_Matrix_Multiply( FT_Matrix*  a,
  60.                       FT_Matrix*  b )
  61.   {
  62.     FT_Fixed  xx, xy, yx, yy;
  63.  
  64.  
  65.     if ( !a || !b )
  66.       return;
  67.  
  68.     xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );
  69.     xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );
  70.     yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );
  71.     yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );
  72.  
  73.     b->xx = xx;  b->xy = xy;
  74.     b->yx = yx;  b->yy = yy;
  75.   }
  76.  
  77.  
  78.   /* documentation is in ftglyph.h */
  79.  
  80.   FT_EXPORT_DEF( FT_Error )
  81.   FT_Matrix_Invert( FT_Matrix*  matrix )
  82.   {
  83.     FT_Pos  delta, xx, yy;
  84.  
  85.  
  86.     if ( !matrix )
  87.       return FT_Err_Invalid_Argument;
  88.  
  89.     /* compute discriminant */
  90.     delta = FT_MulFix( matrix->xx, matrix->yy ) -
  91.             FT_MulFix( matrix->xy, matrix->yx );
  92.  
  93.     if ( !delta )
  94.       return FT_Err_Invalid_Argument;  /* matrix can't be inverted */
  95.  
  96.     matrix->xy = - FT_DivFix( matrix->xy, delta );
  97.     matrix->yx = - FT_DivFix( matrix->yx, delta );
  98.  
  99.     xx = matrix->xx;
  100.     yy = matrix->yy;
  101.  
  102.     matrix->xx = FT_DivFix( yy, delta );
  103.     matrix->yy = FT_DivFix( xx, delta );
  104.  
  105.     return FT_Err_Ok;
  106.   }
  107.  
  108.  
  109.   /*************************************************************************/
  110.   /*************************************************************************/
  111.   /****                                                                 ****/
  112.   /****   FT_BitmapGlyph support                                        ****/
  113.   /****                                                                 ****/
  114.   /*************************************************************************/
  115.   /*************************************************************************/
  116.  
  117.   static FT_Error
  118.   ft_bitmap_copy( FT_Memory   memory,
  119.                   FT_Bitmap*  source,
  120.                   FT_Bitmap*  target )
  121.   {
  122.     FT_Error  error;
  123.     FT_Int    pitch = source->pitch;
  124.     FT_ULong  size;
  125.  
  126.  
  127.     *target = *source;
  128.  
  129.     if ( pitch < 0 )
  130.       pitch = -pitch;
  131.  
  132.     size = (FT_ULong)( pitch * source->rows );
  133.  
  134.     if ( !ALLOC( target->buffer, size ) )
  135.       MEM_Copy( target->buffer, source->buffer, size );
  136.  
  137.     return error;
  138.   }
  139.  
  140.  
  141.   static FT_Error
  142.   ft_bitmap_glyph_init( FT_BitmapGlyph  glyph,
  143.                         FT_GlyphSlot    slot )
  144.   {
  145.     FT_Error    error   = FT_Err_Ok;
  146.     FT_Library  library = FT_GLYPH(glyph)->library;
  147.     FT_Memory   memory  = library->memory;
  148.  
  149.  
  150.     if ( slot->format != ft_glyph_format_bitmap )
  151.     {
  152.       error = FT_Err_Invalid_Glyph_Format;
  153.       goto Exit;
  154.     }
  155.  
  156.     /* grab the bitmap in the slot - do lazy copying whenever possible */
  157.     glyph->bitmap = slot->bitmap;
  158.     glyph->left   = slot->bitmap_left;
  159.     glyph->top    = slot->bitmap_top;
  160.  
  161.     if ( slot->flags & ft_glyph_own_bitmap )
  162.       slot->flags &= ~ft_glyph_own_bitmap;
  163.     else
  164.     {
  165.       /* copy the bitmap into a new buffer */
  166.       error = ft_bitmap_copy( memory, &slot->bitmap, &glyph->bitmap );
  167.     }
  168.  
  169.   Exit:
  170.     return error;
  171.   }
  172.  
  173.  
  174.   static FT_Error
  175.   ft_bitmap_glyph_copy( FT_BitmapGlyph  source,
  176.                         FT_BitmapGlyph  target )
  177.   {
  178.     FT_Memory  memory = source->root.library->memory;
  179.  
  180.  
  181.     target->left = source->left;
  182.     target->top  = source->top;
  183.  
  184.     return ft_bitmap_copy( memory, &source->bitmap, &target->bitmap );
  185.   }
  186.  
  187.  
  188.   static void
  189.   ft_bitmap_glyph_done( FT_BitmapGlyph  glyph )
  190.   {
  191.     FT_Memory  memory = FT_GLYPH(glyph)->library->memory;
  192.  
  193.  
  194.     FREE( glyph->bitmap.buffer );
  195.   }
  196.  
  197.  
  198.   static void
  199.   ft_bitmap_glyph_bbox( FT_BitmapGlyph  glyph,
  200.                         FT_BBox*        cbox )
  201.   {
  202.     cbox->xMin = glyph->left << 6;
  203.     cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 );
  204.     cbox->yMax = glyph->top << 6;
  205.     cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 );
  206.   }
  207.  
  208.  
  209.   const FT_Glyph_Class  ft_bitmap_glyph_class =
  210.   {
  211.     sizeof( FT_BitmapGlyphRec ),
  212.     ft_glyph_format_bitmap,
  213.  
  214.     (FT_Glyph_Init_Func)     ft_bitmap_glyph_init,
  215.     (FT_Glyph_Done_Func)     ft_bitmap_glyph_done,
  216.     (FT_Glyph_Copy_Func)     ft_bitmap_glyph_copy,
  217.     (FT_Glyph_Transform_Func)0,
  218.     (FT_Glyph_BBox_Func)     ft_bitmap_glyph_bbox,
  219.     (FT_Glyph_Prepare_Func)  0
  220.   };
  221.  
  222.  
  223.   /*************************************************************************/
  224.   /*************************************************************************/
  225.   /****                                                                 ****/
  226.   /****   FT_OutlineGlyph support                                       ****/
  227.   /****                                                                 ****/
  228.   /*************************************************************************/
  229.   /*************************************************************************/
  230.  
  231.  
  232.   static FT_Error
  233.   ft_outline_glyph_init( FT_OutlineGlyph  glyph,
  234.                          FT_GlyphSlot     slot )
  235.   {
  236.     FT_Error     error   = FT_Err_Ok;
  237.     FT_Library   library = FT_GLYPH(glyph)->library;
  238.     FT_Outline*  source  = &slot->outline;
  239.     FT_Outline*  target  = &glyph->outline;
  240.  
  241.  
  242.     /* check format in glyph slot */
  243.     if ( slot->format != ft_glyph_format_outline )
  244.     {
  245.       error = FT_Err_Invalid_Glyph_Format;
  246.       goto Exit;
  247.     }
  248.  
  249.     /* allocate new outline */
  250.     error = FT_Outline_New( library, source->n_points, source->n_contours,
  251.                             &glyph->outline );
  252.     if ( error )
  253.       goto Exit;
  254.  
  255.     /* copy it */
  256.     MEM_Copy( target->points, source->points,
  257.               source->n_points * sizeof ( FT_Vector ) );
  258.  
  259.     MEM_Copy( target->tags, source->tags,
  260.               source->n_points * sizeof ( FT_Byte ) );
  261.  
  262.     MEM_Copy( target->contours, source->contours,
  263.               source->n_contours * sizeof ( FT_Short ) );
  264.  
  265.     /* copy all flags, except the `ft_outline_owner' one */
  266.     target->flags = source->flags | ft_outline_owner;
  267.  
  268.   Exit:
  269.     return error;
  270.   }
  271.  
  272.  
  273.   static void
  274.   ft_outline_glyph_done( FT_OutlineGlyph  glyph )
  275.   {
  276.     FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline );
  277.   }
  278.  
  279.  
  280.   static FT_Error
  281.   ft_outline_glyph_copy( FT_OutlineGlyph  source,
  282.                          FT_OutlineGlyph  target )
  283.   {
  284.     FT_Error    error;
  285.     FT_Library  library = FT_GLYPH( source )->library;
  286.  
  287.  
  288.     error = FT_Outline_New( library, source->outline.n_points,
  289.                             source->outline.n_contours, &target->outline );
  290.     if ( !error )
  291.       FT_Outline_Copy( &source->outline, &target->outline );
  292.  
  293.     return error;
  294.   }
  295.  
  296.  
  297.   static void
  298.   ft_outline_glyph_transform( FT_OutlineGlyph  glyph,
  299.                               FT_Matrix*       matrix,
  300.                               FT_Vector*       delta )
  301.   {
  302.     if ( matrix )
  303.       FT_Outline_Transform( &glyph->outline, matrix );
  304.  
  305.     if ( delta )
  306.       FT_Outline_Translate( &glyph->outline, delta->x, delta->y );
  307.   }
  308.  
  309.  
  310.   static void
  311.   ft_outline_glyph_bbox( FT_OutlineGlyph  glyph,
  312.                          FT_BBox*         bbox )
  313.   {
  314.     FT_Outline_Get_CBox( &glyph->outline, bbox );
  315.   }
  316.  
  317.  
  318.   static FT_Error
  319.   ft_outline_glyph_prepare( FT_OutlineGlyph  glyph,
  320.                             FT_GlyphSlot     slot )
  321.   {
  322.     slot->format         = ft_glyph_format_outline;
  323.     slot->outline        = glyph->outline;
  324.     slot->outline.flags &= ~ft_outline_owner;
  325.  
  326.     return FT_Err_Ok;
  327.   }
  328.  
  329.  
  330.   const FT_Glyph_Class  ft_outline_glyph_class =
  331.   {
  332.     sizeof( FT_OutlineGlyphRec ),
  333.     ft_glyph_format_outline,
  334.  
  335.     (FT_Glyph_Init_Func)     ft_outline_glyph_init,
  336.     (FT_Glyph_Done_Func)     ft_outline_glyph_done,
  337.     (FT_Glyph_Copy_Func)     ft_outline_glyph_copy,
  338.     (FT_Glyph_Transform_Func)ft_outline_glyph_transform,
  339.     (FT_Glyph_BBox_Func)     ft_outline_glyph_bbox,
  340.     (FT_Glyph_Prepare_Func)  ft_outline_glyph_prepare
  341.   };
  342.  
  343.  
  344.   /*************************************************************************/
  345.   /*************************************************************************/
  346.   /****                                                                 ****/
  347.   /****   FT_Glyph class and API                                        ****/
  348.   /****                                                                 ****/
  349.   /*************************************************************************/
  350.   /*************************************************************************/
  351.  
  352.    static FT_Error
  353.    ft_new_glyph( FT_Library             library,
  354.                  const FT_Glyph_Class*  clazz,
  355.                  FT_Glyph*              aglyph )
  356.    {
  357.      FT_Memory  memory = library->memory;
  358.      FT_Error   error;
  359.      FT_Glyph   glyph;
  360.  
  361.  
  362.      *aglyph = 0;
  363.  
  364.      if ( !ALLOC( glyph, clazz->glyph_size ) )
  365.      {
  366.        glyph->library = library;
  367.        glyph->clazz   = clazz;
  368.        glyph->format  = clazz->glyph_format;
  369.  
  370.        *aglyph = glyph;
  371.      }
  372.  
  373.      return error;
  374.    }
  375.  
  376.  
  377.   /* documentation is in ftglyph.h */
  378.  
  379.   FT_EXPORT_DEF( FT_Error )
  380.   FT_Glyph_Copy( FT_Glyph   source,
  381.                  FT_Glyph  *target )
  382.   {
  383.     FT_Glyph               copy;
  384.     FT_Error               error;
  385.     const FT_Glyph_Class*  clazz;
  386.  
  387.  
  388.     /* check arguments */
  389.     if ( !target || !source || !source->clazz )
  390.     {
  391.       error = FT_Err_Invalid_Argument;
  392.       goto Exit;
  393.     }
  394.  
  395.     *target = 0;
  396.  
  397.     clazz = source->clazz;
  398.     error = ft_new_glyph( source->library, clazz, © );
  399.     if ( error )
  400.       goto Exit;
  401.  
  402.     copy->advance = source->advance;
  403.     copy->format  = source->format;
  404.  
  405.     if ( clazz->glyph_copy )
  406.       error = clazz->glyph_copy( source, copy );
  407.  
  408.     if ( error )
  409.       FT_Done_Glyph( copy );
  410.     else
  411.       *target = copy;
  412.  
  413.   Exit:
  414.     return error;
  415.   }
  416.  
  417.  
  418.   /* documentation is in ftglyph.h */
  419.  
  420.   FT_EXPORT_DEF( FT_Error )
  421.   FT_Get_Glyph( FT_GlyphSlot  slot,
  422.                 FT_Glyph     *aglyph )
  423.   {
  424.     FT_Library  library = slot->library;
  425.     FT_Error    error;
  426.     FT_Glyph    glyph;
  427.  
  428.     const FT_Glyph_Class*  clazz = 0;
  429.  
  430.  
  431.     if ( !slot )
  432.       return FT_Err_Invalid_Slot_Handle;
  433.  
  434.     if ( !aglyph )
  435.       return FT_Err_Invalid_Argument;
  436.  
  437.     /* if it is a bitmap, that's easy :-) */
  438.     if ( slot->format == ft_glyph_format_bitmap )
  439.       clazz = &ft_bitmap_glyph_class;
  440.  
  441.     /* it it is an outline too */
  442.     else if ( slot->format == ft_glyph_format_outline )
  443.       clazz = &ft_outline_glyph_class;
  444.  
  445.     else
  446.     {
  447.       /* try to find a renderer that supports the glyph image format */
  448.       FT_Renderer  render = FT_Lookup_Renderer( library, slot->format, 0 );
  449.  
  450.  
  451.       if ( render )
  452.         clazz = &render->glyph_class;
  453.     }
  454.  
  455.     if ( !clazz )
  456.     {
  457.       error = FT_Err_Invalid_Glyph_Format;
  458.       goto Exit;
  459.     }
  460.  
  461.     /* create FT_Glyph object */
  462.     error = ft_new_glyph( library, clazz, &glyph );
  463.     if ( error )
  464.       goto Exit;
  465.  
  466.     /* copy advance while converting it to 16.16 format */
  467.     glyph->advance.x = slot->advance.x << 10;
  468.     glyph->advance.y = slot->advance.y << 10;
  469.  
  470.     /* now import the image from the glyph slot */
  471.     error = clazz->glyph_init( glyph, slot );
  472.  
  473.     /* if an error occurred, destroy the glyph */
  474.     if ( error )
  475.       FT_Done_Glyph( glyph );
  476.     else
  477.       *aglyph = glyph;
  478.  
  479.   Exit:
  480.     return error;
  481.   }
  482.  
  483.  
  484.   /* documentation is in ftglyph.h */
  485.  
  486.   FT_EXPORT_DEF( FT_Error )
  487.   FT_Glyph_Transform( FT_Glyph    glyph,
  488.                       FT_Matrix*  matrix,
  489.                       FT_Vector*  delta )
  490.   {
  491.     const FT_Glyph_Class*  clazz;
  492.     FT_Error               error = FT_Err_Ok;
  493.  
  494.  
  495.     if ( !glyph || !glyph->clazz )
  496.       error = FT_Err_Invalid_Argument;
  497.     else
  498.     {
  499.       clazz = glyph->clazz;
  500.       if ( clazz->glyph_transform )
  501.       {
  502.         /* transform glyph image */
  503.         clazz->glyph_transform( glyph, matrix, delta );
  504.  
  505.         /* transform advance vector */
  506.         if ( matrix )
  507.           FT_Vector_Transform( &glyph->advance, matrix );
  508.       }
  509.       else
  510.         error = FT_Err_Invalid_Glyph_Format;
  511.     }
  512.     return error;
  513.   }
  514.  
  515.  
  516.   /* documentation is in ftglyph.h */
  517.  
  518.   FT_EXPORT_DEF( void )
  519.   FT_Glyph_Get_CBox( FT_Glyph  glyph,
  520.                      FT_UInt   bbox_mode,
  521.                      FT_BBox  *acbox )
  522.   {
  523.     const FT_Glyph_Class*  clazz;
  524.  
  525.  
  526.     if ( !acbox )
  527.       return;
  528.  
  529.     acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0;
  530.  
  531.     if ( !glyph || !glyph->clazz )
  532.       return;
  533.     else
  534.     {
  535.       clazz = glyph->clazz;
  536.       if ( !clazz->glyph_bbox )
  537.         return;
  538.       else
  539.       {
  540.         /* retrieve bbox in 26.6 coordinates */
  541.         clazz->glyph_bbox( glyph, acbox );
  542.  
  543.         /* perform grid fitting if needed */
  544.         if ( bbox_mode & ft_glyph_bbox_gridfit )
  545.         {
  546.           acbox->xMin &= -64;
  547.           acbox->yMin &= -64;
  548.           acbox->xMax  = ( acbox->xMax + 63 ) & -64;
  549.           acbox->yMax  = ( acbox->yMax + 63 ) & -64;
  550.         }
  551.  
  552.         /* convert to integer pixels if needed */
  553.         if ( bbox_mode & ft_glyph_bbox_truncate )
  554.         {
  555.           acbox->xMin >>= 6;
  556.           acbox->yMin >>= 6;
  557.           acbox->xMax >>= 6;
  558.           acbox->yMax >>= 6;
  559.         }
  560.       }
  561.     }
  562.     return;
  563.   }
  564.  
  565.  
  566.   /* documentation is in ftglyph.h */
  567.  
  568.   FT_EXPORT_DEF( FT_Error )
  569.   FT_Glyph_To_Bitmap( FT_Glyph*   the_glyph,
  570.                       FT_ULong    render_mode,
  571.                       FT_Vector*  origin,
  572.                       FT_Bool     destroy )
  573.   {
  574.     FT_GlyphSlotRec  dummy;
  575.     FT_Error         error;
  576.     FT_Glyph         glyph;
  577.     FT_BitmapGlyph   bitmap = NULL;
  578.  
  579.     const FT_Glyph_Class*  clazz;
  580.  
  581.  
  582.     /* check argument */
  583.     if ( !the_glyph )
  584.       goto Bad;
  585.  
  586.     /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
  587.     /* then calling FT_Render_Glyph_Internal()                            */
  588.  
  589.     glyph = *the_glyph;
  590.     if ( !glyph )
  591.       goto Bad;
  592.  
  593.     clazz = glyph->clazz;
  594.     if ( !clazz || !clazz->glyph_prepare )
  595.       goto Bad;
  596.  
  597.     MEM_Set( &dummy, 0, sizeof ( dummy ) );
  598.     dummy.library = glyph->library;
  599.     dummy.format  = clazz->glyph_format;
  600.  
  601.     /* create result bitmap glyph */
  602.     error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class,
  603.                           (FT_Glyph*)&bitmap );
  604.     if ( error )
  605.       goto Exit;
  606.  
  607. #if 0
  608.     /* if `origin' is set, translate the glyph image */
  609.     if ( origin )
  610.       FT_Glyph_Transform( glyph, 0, origin );
  611. #else
  612.     FT_UNUSED( origin );
  613. #endif
  614.  
  615.     /* prepare dummy slot for rendering */
  616.     error = clazz->glyph_prepare( glyph, &dummy );
  617.     if ( !error )
  618.       error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
  619.  
  620. #if 0
  621.     if ( !destroy && origin )
  622.     {
  623.       FT_Vector  v;
  624.  
  625.  
  626.       v.x = -origin->x;
  627.       v.y = -origin->y;
  628.       FT_Glyph_Transform( glyph, 0, &v );
  629.     }
  630. #endif
  631.  
  632.     if ( error )
  633.       goto Exit;
  634.  
  635.     /* in case of success, copy the bitmap to the glyph bitmap */
  636.     error = ft_bitmap_glyph_init( bitmap, &dummy );
  637.     if ( error )
  638.       goto Exit;
  639.  
  640.     /* copy advance */
  641.     bitmap->root.advance = glyph->advance;
  642.  
  643.     if ( destroy )
  644.       FT_Done_Glyph( glyph );
  645.  
  646.     *the_glyph = FT_GLYPH( bitmap );
  647.  
  648.   Exit:
  649.     if ( error && bitmap )
  650.       FT_Done_Glyph( FT_GLYPH( bitmap ) );
  651.  
  652.     return error;
  653.  
  654.   Bad:
  655.     error = FT_Err_Invalid_Argument;
  656.     goto Exit;
  657.   }
  658.  
  659.  
  660.   /* documentation is in ftglyph.h */
  661.  
  662.   FT_EXPORT_DEF( void )
  663.   FT_Done_Glyph( FT_Glyph  glyph )
  664.   {
  665.     if ( glyph )
  666.     {
  667.       FT_Memory              memory = glyph->library->memory;
  668.       const FT_Glyph_Class*  clazz  = glyph->clazz;
  669.  
  670.  
  671.       if ( clazz->glyph_done )
  672.         clazz->glyph_done( glyph );
  673.  
  674.       FREE( glyph );
  675.     }
  676.   }
  677.  
  678.  
  679. /* END */
  680.